#ifndef __PROCESS_POOL_HPP__
#define __PROCESS_POOL_HPP__
#include"Task.hpp"
#include <iostream>
#include <vector>
#include <unistd.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
void fun()
{
    std::cout << "hello hpp\n"
              << std::endl;
}

class Channel
{
public:
    Channel(int wfd, pid_t pid) 
    : _wfd(wfd)
    , _pid(pid)
    {
        _name = "channel-"+std::to_string(_wfd)+"-"+std::to_string(_pid);
    }
    int GetWfd()
    {
        return _wfd;
    }
    pid_t GetPid()
    {
        return _pid;
    }
    std::string GetName()
    {
        return _name;
    }
    void Send(int code)
    {
        int n = write(_wfd,&code,sizeof(code));
        (void)n;
    }
    void Close()
    {
        close(_wfd);
    }
    void Wait()
    {
        pid_t rid = waitpid(_pid,NULL,0);
        (void)rid;
    }
    ~Channel()
    {
    }
private:
    int _wfd;
    pid_t _pid;
    std::string _name;
};
class ChannelManager
    {
    public:
        ChannelManager()
        : _next(0)
        {
        }
        Channel &Select()
        {
            auto &c = _channels[_next];
            _next++;
            _next%=_channels.size();
            return c;
        }
        void Insert(int wfd,int subid)
        {
            _channels.emplace_back(wfd,subid);
            //Channel c(wfd,subid);
            //_channels.push_back(c);
        }
        void printChnnls()
        {
            for(size_t i=0;i<_channels.size();i++)
            {
                std::cout<<"wfd:"<<_channels[i].GetWfd()<<" pid:"<<_channels[i].GetPid()<<std::endl;
            }
        } 
        void StopSubprocess()
        {
        //发送信号给子进程
            for(auto & Channel:_channels)
            {
                Channel.Close();
                std::cout<<"关闭子进程"<<Channel.GetName()<<std::endl;
            }
        }
        void WaitSubprocess()
        {
            
            for(auto & Channel:_channels)
            {
                
                Channel.Wait();
                std::cout<<"回收子进程"<<Channel.GetName()<<std::endl;
            }
        }
        void CloseandWait()
        {
            
            for(auto & Channel:_channels)
            {
                Channel.Close();
                std::cout<<"关闭子进程"<<Channel.GetName()<<std::endl;
                Channel.Wait();
                std::cout<<"回收子进程"<<Channel.GetName()<<std::endl;
            }
        }
        ~ChannelManager()
        {

        }
    private:
        std::vector <Channel> _channels;
        int _next;
    };
const int gdefaultnum = 6;
class ProcessPool
{
public:
    ProcessPool(int num) 
    : _process_num(num)
    {
        _tm.Resgister_task(PrintLog);
        _tm.Resgister_task(Download);
        _tm.Resgister_task(Upload);
    }
    void Work(int rfd)
    {
        while(true)
        {
            int code = 0;
            ssize_t n = read(rfd,&code,sizeof(code));
            if(n > 0)
            {
                if(n != sizeof(code))
                {
                    continue;
                }
                std::cout<<"子进程["<<getpid()<<"]收到的任务码"<<code<<std::endl;
                _tm.Execute(code);
            }
            else if(n == 0)
            {
                
                std::cout<<"子进程退出"<<std::endl;
                break;
            }
            else
            {
                std::cerr<<"读取错误"<<std::endl;
                break;
            }
           
            
        }
    }
    bool Creat()
    {
        for(int i=0;i<_process_num;i++)
        {
            //Creat Pipe

            int pipefd[2]={0};
            int n = pipe(pipefd);
            if(n < 0)
            {

                return false;
            }
            pid_t subid = fork();
            if(subid < 0)
            {
                return false;
            }
            else if(subid == 0)//child read
            {
                //child process
                close(pipefd[1]);
                Work(pipefd[0]);
                close(pipefd[0]);
                exit(0);
            }
            else //parent write
            {
                //parent process
                close(pipefd[0]);
                _cm.Insert(pipefd[1],subid);
                
                //close(pipefd[1]);

            }
        }
        return true;
    }
    void Debug()
    {
        _cm.printChnnls();
    }
    void PushTask()
    {
        //负载均衡地选择一个信道
        
        //1.轮询调度
        //2.随机访问
        //3.channel添加负载指标
        //选择方案一
        //选择一个任务
        int code =_tm.Code();

        //1.选择一个信道/子进程
        auto & c = _cm.Select();
        std::cout<<"选择的子进程"<<c.GetName()<<std::endl;


        //2.通过信道发送任务码
        c.Send(code);
        std::cout<<"父进程发送任务码"<<code<<std::endl;
       

    }  
    void Destroy()
    {
        //关闭父进程的wfd
        _cm.StopSubprocess();
        //回收子进程
        _cm.WaitSubprocess();
        
    }
    
    ~ProcessPool()
    {
    }
private:
    ChannelManager _cm;
    int _process_num;
    TaskManager _tm;
};
#endif
